package org.liuh.designs.spider;

import lombok.NoArgsConstructor;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.liuh.designs.spider.dtos.AddressNode;
import org.liuh.designs.spider.utils.HttpClientUtil;
import org.liuh.designs.spider.utils.SpiderHttpUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @ClassName: AreaSpiderCityTask
 * @Description: 抓取所有的区/县信息
 * @Author: liuh
 * @Date: 2020/9/30 14:54
 * @Version: 1.0
 */
@NoArgsConstructor
public class AreaSpiderCityTask implements Runnable {

    // 东莞、中山、儋州市下面直接是 town： 城镇..没有county..
    public static final List<String> SPECIAL_CITY = Arrays.asList("460400000000", "441900000000", "442000000000");

    private AddressNode cityNode;

    private CountDownLatch cityDown;

    private AreaConstant.HttpUtilEnum utilEnum;

    public AreaSpiderCityTask(AddressNode cityNode, CountDownLatch cityDown, AreaConstant.HttpUtilEnum utilEnum) {
        this.cityNode = cityNode;
        this.cityDown = cityDown;
        this.utilEnum = utilEnum;
    }

    @Override
    public void run() {
        try {
            String tmpUrl = cityNode.getNodeUrl();
            String sourceUrl = cityNode.getParentNode().getNodeUrl();
            if (tmpUrl == null) {
                return;
            }
            String tmpCountry = null;
            if (utilEnum == AreaConstant.HttpUtilEnum.NORMAL) {
                tmpCountry = SpiderHttpUtils.sendGet(false, tmpUrl, null, null, AreaConstant.CHAR_SET);
            } else if (utilEnum == AreaConstant.HttpUtilEnum.HTTP_CLIENT) {
                tmpCountry = HttpClientUtil.doHttpGet(tmpUrl, sourceUrl, null, AreaConstant.CHAR_SET);
            }
            if (tmpCountry == null) {
                return;
            }
            Document countryPage = Jsoup.parse(tmpCountry);
            if (countryPage == null) {
                return;
            }
            // 需要分割开来进行null值判断..
            Elements countryTrs = countryPage.getElementsByClass(AreaConstant.getNameByClass(AreaConstant.ClassEnum.county, AreaConstant.TagEnum.table));
            if (countryTrs == null || countryTrs.isEmpty()) {
                countryTrs = countryPage.getElementsByClass(AreaConstant.getNameByClass(AreaConstant.ClassEnum.town, AreaConstant.TagEnum.table));
            }
            if (countryTrs == null || countryTrs.isEmpty()) {
                return;
            }
            Elements elementsByClass = countryTrs.first().getElementsByClass(AreaConstant.getNameByClass(AreaConstant.ClassEnum.county, AreaConstant.TagEnum.tr));
            if (elementsByClass == null || elementsByClass.isEmpty()) {
                elementsByClass = countryTrs.first().getElementsByClass(AreaConstant.getNameByClass(AreaConstant.ClassEnum.town, AreaConstant.TagEnum.tr));
            }
            if (elementsByClass == null || elementsByClass.isEmpty()) {
                return;
            }
            List<AddressNode> countryNodes = new ArrayList<>();
            AddressNode countyNode;
            for (Element element : elementsByClass) {
                Elements countyTdTags = element.getElementsByTag(AreaConstant.TagEnum.td.name());
                if (countyTdTags == null) {
                    continue;
                }
                //code
                Element countyCodeElement = countyTdTags.get(0);
                String countyCode = countyCodeElement.text();
                if (countyCode == null || countyCode.isEmpty()) {
                    continue;
                }
                countyNode = new AddressNode();
                Element countyLinkA = countyCodeElement.getElementsByTag(AreaConstant.TagEnum.a.name()).first();
                if (countyLinkA != null) {
                    String countyHref = countyLinkA.attr(AreaConstant.AttrEnum.href.name());
                    countyNode.setNodeUrl(AreaConstant.getFullLinkUrl(tmpUrl, countyHref, AreaConstant.ClassEnum.county));
                }
                //name
                Element countyLinkB = countyTdTags.get(1).getElementsByTag(AreaConstant.TagEnum.a.name()).first();
                if (countyLinkB == null) {
                    countyLinkB = countyTdTags.get(1);
                }
                String countyname = countyLinkB.text();
                countyNode.setAddressCode(countyCode);
                countyNode.setAddressName(countyname);
                countyNode.setParentNode(cityNode);
                if (SPECIAL_CITY.contains(cityNode.getAddressCode())) {
                    // 镇/街道..
                    countyNode.setLevel(AreaConstant.LevelEnum.LEVEL_4.getLevel());
                } else {
                    // 区县
                    countyNode.setLevel(AreaConstant.LevelEnum.LEVEL_3.getLevel());
                }
                countryNodes.add(countyNode);
            }
            cityNode.setChildNodeList(countryNodes);
            System.out.println(String.format("%s， 处理完毕！-- 区县数量:%s ", cityNode.getAddressName(), countryNodes.size()));
        } catch (Exception ex) {
            System.out.println(String.format("城市：%s, code: %s 获取区县异常； ", cityNode.getAddressName(), cityNode.getAddressCode()));
        } finally {
            cityDown.countDown();
        }
    }
}
